// utils/request.js - Axios请求封装 (Vue 3版本) - 修复版
import axios from 'axios'
import { ElMessage, ElLoading } from 'element-plus'
import router from '@/router'
import { useUserStore } from '@/stores/user'

export const baseBackURL = 'http://192.168.0.152:7800/apis'

// 创建axios实例
const service = axios.create({
    baseURL: import.meta.env.VITE_API_BASE_URL || baseBackURL,
    timeout: 30000,
    headers: {
        'Content-Type': 'application/json;charset=UTF-8'
    }
})

let loadingInstance = null
let isRefreshing = false // 是否正在刷新token
let requestQueue = [] // 请求队列

// 请求拦截器
service.interceptors.request.use(
    config => {
        // 添加loading效果
        if (config.loading !== false) {
            loadingInstance = ElLoading.service({
                text: config.loadingText || '请求中...',
                spinner: 'el-icon-loading',
                background: 'rgba(0, 0, 0, 0.7)'
            })
        }

        // 添加认证token
        const token = getToken()
        if (token) {
            config.headers['Authorization'] = `Bearer ${token}`
        }

        // 添加请求ID
        config.headers['X-Request-ID'] = generateRequestId()

        // 添加时间戳（防止缓存）
        if (config.method === 'get') {
            config.params = {
                ...config.params,
                _t: Date.now()
            }
        }

        console.log('发送请求:', config)
        return config
    },
    error => {
        if (loadingInstance) {
            loadingInstance.close()
        }
        console.error('请求错误:', error)
        return Promise.reject(error)
    }
)

// 响应拦截器
service.interceptors.response.use(
    response => {
        if (loadingInstance) {
            loadingInstance.close()
        }

        const res = response.data
        console.log('收到响应:', res)

        // 处理文件下载
        if (response.config.responseType === 'blob') {
            return response
        }

        // 处理API响应
        if (res.success === false || res.code !== 200) {
            // 如果是401错误，交给错误拦截器处理
            if (res.code === 401) {
                return Promise.reject({
                    response: {
                        status: 401,
                        data: res
                    },
                    config: response.config
                })
            }

            ElMessage.error( res.message || '请求失败')
            return Promise.reject(new Error(res.message || '请求失败'))
        }

        return res
    },
    async error => {
        if (loadingInstance) {
            loadingInstance.close()
        }

        console.error('响应错误:', error)

        let message = '网络错误'
        const { response, config } = error

        if (response) {
            const data = response.data
            const code = response.data.code

            switch (code) {
                case 400:
                    message = data.message || '请求参数错误'
                    break
                case 401:
                    // token过期或无效 - 关键修复点
                    console.log('检测到401错误，开始处理token过期')
                    return await handleTokenExpired(config, error)
                case 403:
                    message = '拒绝访问'
                    break
                case 404:
                    message = '请求地址出错'
                    break
                case 408:
                    message = '请求超时'
                    break
                case 500:
                    message = data.message || '服务器内部错误'
                    break
                case 501:
                    message = '服务未实现'
                    break
                case 502:
                    message = '网关错误'
                    break
                case 503:
                    message = '服务不可用'
                    break
                case 504:
                    message = '网关超时'
                    break
                case 505:
                    message = 'HTTP版本不受支持'
                    break
                default:
                    message = data?.message || `连接错误${code}`
            }
        } else if (error.code === 'ECONNABORTED') {
            message = '请求超时'
        } else if (error.message.includes('Network Error')) {
            message = '网络连接异常'
        }

        // 只有非401错误才显示错误提示
        if (!response || response.data.code !== 401) {
            ElMessage.error(message)
        }

        return Promise.reject(error)
    }
)

// 处理token过期 - 关键修复
async function handleTokenExpired(config, error) {
    console.log('开始处理token过期，当前URL:', config.url)

    // 如果是登录或刷新token请求，直接跳转登录页
    if (config.url.includes('/login') || config.url.includes('/refresh-token')) {
        console.log('登录相关请求失败，直接跳转登录页')
        redirectToLogin()
        return Promise.reject(error)
    }

    // 如果正在刷新token，将请求加入队列
    if (isRefreshing) {
        console.log('正在刷新token，请求加入队列')
        return new Promise((resolve, reject) => {
            requestQueue.push({ resolve, reject, config })
        })
    }

    isRefreshing = true
    console.log('开始刷新token')

    try {
        // 获取用户store
        const userStore = useUserStore()

        // 检查是否有有效的token可以刷新
        const currentToken = getToken()
        if (!currentToken) {
            throw new Error('没有可刷新的token')
        }

        // 尝试刷新token
        const newToken = await userStore.refreshToken()

        // 处理队列中的请求
        console.log('处理队列中的请求，队列长度:', requestQueue.length)
        requestQueue.forEach(({ resolve, config: queueConfig }) => {
            queueConfig.headers['Authorization'] = `Bearer ${newToken}`
            resolve(service(queueConfig))
        })

        // 重新发送当前请求
        config.headers['Authorization'] = `Bearer ${newToken}`
        return service(config)

    } catch (refreshError) {
        console.error('刷新token失败:', refreshError)

        // 清除队列中的请求
        requestQueue.forEach(({ reject }) => {
            reject(refreshError)
        })

        // 清除用户信息并跳转登录
        clearUserData()

        ElMessage.error('登录状态已过期，请重新登录')

        // 跳转到登录页
        redirectToLogin()

        return Promise.reject(refreshError)
    } finally {
        isRefreshing = false
        requestQueue = []
    }
}

// 跳转到登录页 - 关键修复
function redirectToLogin() {
    console.log('准备跳转到登录页，当前路由:', router.currentRoute.value.path)

    // 防止重复跳转
    if (router.currentRoute.value.path === '/login') {
        console.log('当前已在登录页，无需跳转')
        return
    }

    // 保存当前页面路径，登录后可以返回
    const currentPath = router.currentRoute.value.fullPath

    // 跳转到登录页
    router.push({
        path: '/login',
        query: {
            redirect: currentPath !== '/login' ? currentPath : undefined
        }
    }).then(() => {
        console.log('成功跳转到登录页')
    }).catch(err => {
        console.error('跳转登录页失败:', err)
        // 如果路由跳转失败，尝试直接刷新页面到登录页
        window.location.href = '/login'
    })
}

// 清除用户数据
function clearUserData() {
    console.log('清除用户数据')

    // 清除token
    localStorage.removeItem('token')
    sessionStorage.removeItem('token')

    // 清除用户信息
    localStorage.removeItem('userInfo')
    sessionStorage.removeItem('userInfo')

    // 清除用户store
    try {
        const userStore = useUserStore()
        if (userStore && typeof userStore.logout === 'function') {
            userStore.logout()
        }
    } catch (error) {
        console.warn('清除用户store失败:', error)
    }
}

// 获取token的辅助函数
function getToken() {
    return localStorage.getItem('token') || sessionStorage.getItem('token')
}

// 生成请求ID
function generateRequestId() {
    return 'req_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9)
}

// 导出封装的请求方法
export default {
    get(url, params, config = {}) {
        return service({
            method: 'get',
            url,
            params,
            ...config
        })
    },

    post(url, data, config = {}) {
        return service({
            method: 'post',
            url,
            data,
            ...config
        })
    },

    put(url, data, config = {}) {
        return service({
            method: 'put',
            url,
            data,
            ...config
        })
    },

    delete(url, config = {}) {
        return service({
            method: 'delete',
            url,
            ...config
        })
    },

    download(url, params, filename, config = {}) {
        return service({
            method: 'get',
            url,
            params,
            responseType: 'blob',
            timeout: 60000, // 文件下载超时时间设长一点
            ...config
        }).then(response => {
            const blob = new Blob([response.data])
            const downloadUrl = window.URL.createObjectURL(blob)
            const a = document.createElement('a')
            a.href = downloadUrl
            a.download = filename || 'download'
            a.click()
            window.URL.revokeObjectURL(downloadUrl)
            return response
        })
    }
}